From a704a1efedaa4eeb545348b4889b3f499d454c0c Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 19 Jan 2021 12:42:34 -0600 Subject: [PATCH] Recover from db errors while building insert statements --- src/pgwui_bulk_upload/exceptions.py | 10 ++++++++++ src/pgwui_bulk_upload/views/bulk_upload.py | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/pgwui_bulk_upload/exceptions.py b/src/pgwui_bulk_upload/exceptions.py index d7ee256..08fad42 100644 --- a/src/pgwui_bulk_upload/exceptions.py +++ b/src/pgwui_bulk_upload/exceptions.py @@ -97,6 +97,16 @@ class CannotReadError(Error): f'The error is: {exp}') +class CannotRollbackError(Error): + def __init__(self, exp): + super().__init__( + 'Cannot roll back the current transaction', + 'The transaction has failed and must roll back before ' + 'the database can again be queried about relations and ' + 'their columns', + f'The error from psycopg2 is: ({exp})') + + class BadMapFileError(Error): pass diff --git a/src/pgwui_bulk_upload/views/bulk_upload.py b/src/pgwui_bulk_upload/views/bulk_upload.py index b540297..1043d7f 100644 --- a/src/pgwui_bulk_upload/views/bulk_upload.py +++ b/src/pgwui_bulk_upload/views/bulk_upload.py @@ -542,6 +542,7 @@ class BulkTableUploadHandler(BaseTableUploadHandler): quotecols = self.quote_columns() column_quoter = self.get_column_quoter(quotecols) + in_trans = True i_map = dict() errors = [] for fileinfo in self.data.filedata(): @@ -553,6 +554,20 @@ class BulkTableUploadHandler(BaseTableUploadHandler): map_description(fileinfo.filepath, fileinfo.relation), fileinfo.filepath, fileinfo.relation) errors.append(exp) + if in_trans: + # In order to continue to query the db after a db error + # the current transaction must be rolled back. + # Because we know we're going to abort, don't start a + # new transaction. + try: + self.cur.execute('ROLLBACK;') + except psycopg2.DatabaseError as exp: + err = ex.CannotRollbackError(exp) + err.color(map_description(fileinfo.filepath, + fileinfo.relation), + fileinfo.filepath, fileinfo.relation) + errors.append(err) + in_trans = False finally: # Limit number of open files, close the file handle until it # is time to read the file -- 2.34.1